package king.dominic.jlibrary.fragment;

import android.Manifest;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Environment;
import android.support.annotation.RequiresPermission;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import king.dominic.jlibrary.util.HttpUtil;
import king.dominic.jlibrary.util.JSInterface;
import king.dominic.jlibrary.view.OriginWebView;

/**
 * Created by king on 2017/4/6.
 * OriginWebFragment
 */

public class OriginWebFragment extends OriginPermissionFragment {
    private HashMap<String, String[]> mFinishedCallJavascriptMethod;
    private Map<String, OriginWebView> webViews;
    private static final String CACHE_PATH = Environment.getDownloadCacheDirectory().getAbsolutePath();
    private boolean isFirstPageFinished = true;
    private boolean onPageFinished = false;
    private boolean animable = true;

    public void setAnimable(boolean animable) {
        setAnimable(null, animable);
    }

    public void setAnimable(WebView webView, boolean animable) {
        if (webView != null)
            webView.setVisibility(View.VISIBLE);
        this.animable = animable;
    }

    protected OriginWebView getWebView() {
        return getWebView(getClass().getSimpleName());
    }

    protected OriginWebView getWebView(String tag) {
        if (webViews == null) {
            webViews = new HashMap<>();
        }
        if (webViews.containsKey(tag))
            return webViews.get(tag);
        final OriginWebView webView = new OriginWebView(getActivity());
        if (animable)
            webView.setVisibility(View.INVISIBLE);
        webView.setHorizontalScrollBarEnabled(false);
        webView.setVerticalScrollBarEnabled(false);
        webView.setWebViewClient(new WebViewClient() {

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                pageFinished(view, url);
                if (!isFirstPageFinished) return;
                isFirstPageFinished = false;
                if (animable) {
                    Animation animation = AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_in);
                    webView.startAnimation(animation);
                    webView.setVisibility(View.VISIBLE);
                }
                onPageFinished = true;

                //如果在html加载完成之前就有调用js方法
                if (mFinishedCallJavascriptMethod != null) {
                    Set<String> keys = mFinishedCallJavascriptMethod.keySet();
                    for (String k : keys) {
                        JSInterface.callJavascriptMethod(webView, k, mFinishedCallJavascriptMethod.get(k));
                    }
                    mFinishedCallJavascriptMethod.clear();
                }
            }

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                if (onReceivedSslErrorListener(view, handler, error)) {
                    return;
                }
                super.onReceivedSslError(view, handler, error);
            }

            @Override
            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
                if (onReceivedHttpErrorListener(view, request, errorResponse)) {
                    return;
                }
                super.onReceivedHttpError(view, request, errorResponse);
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                if (onReceivedErrorListener(view, request, error)) {
                    return;
                }
                super.onReceivedError(view, request, error);
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                pageStarted(view, url, favicon);
            }
        });
        webViews.put(tag, webView);
        return webView;
    }

    private boolean onReceivedHttpErrorListener(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
        return false;
    }

    protected boolean onReceivedSslErrorListener(WebView view, SslErrorHandler handler, SslError error) {
        return false;
    }

    protected void pageStarted(WebView view, String url, Bitmap favicon) {

    }

    protected void pageFinished(WebView view, String url) {

    }

    protected boolean onReceivedErrorListener(WebView view, WebResourceRequest request, WebResourceError error) {
        return false;
    }

    /**
     * 调用html中的js方法
     *
     * @param webView    webView
     * @param methodName 方法名字
     * @param params     方法参数
     */
    public void addFinishedCallJavascriptMethod(WebView webView, String methodName, String... params) {
        if (onPageFinished) {
            JSInterface.callJavascriptMethod(webView, methodName, params);
            return;
        }
        if (mFinishedCallJavascriptMethod == null) mFinishedCallJavascriptMethod = new HashMap<>();
        mFinishedCallJavascriptMethod.put(methodName, params);
    }

    protected void removeWebView(String tag) {
        if (!webViews.containsKey(tag))
            return;
        onDestroyWebView(webViews.get(tag));
        webViews.remove(tag);
    }

    /**
     * 缩放功能
     */
    public void setWebZoom(WebSettings webSettings) {
        webSettings.setDisplayZoomControls(false);
        webSettings.setSupportZoom(true);
        webSettings.setBuiltInZoomControls(true);
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);

    }

    /**
     * 网络连接及缓存
     */
    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    public void setNetworkCache(WebSettings webSettings) {
        if (HttpUtil.checkConnect(getContext()) == HttpUtil.Connect.NONE) {
            webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
        } else {
            webSettings.setAppCacheEnabled(true);
            webSettings.setAppCachePath(CACHE_PATH);
        }
    }

    @RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)
    @SuppressLint({"SetJavaScriptEnabled", "JavascriptInterface"})
    public OriginWebView getWebView(Object javascriptInterface, String apiName) {
        OriginWebView web = getWebView(apiName);
        WebSettings setting = web.getSettings();
        setting.setJavaScriptEnabled(true);
        web.addJavascriptInterface(javascriptInterface, apiName);
//        setNetworkCache(setting);
        return web;
    }

    protected void onDestroyWebView(WebView webView) {
        webView.getSettings().setBuiltInZoomControls(true);
        webView.setVisibility(View.GONE);
        webView.removeAllViews();
        webView.destroy();
    }

    @Override
    public void onDestroy() {
        if (webViews != null) {
            Collection<OriginWebView> ws = webViews.values();
            for (WebView webView : ws) {
                onDestroyWebView(webView);
            }
        }
        super.onDestroy();
    }

    public static void loadHtml(WebView webView, String html) {
        webView.loadDataWithBaseURL("", html, "text/html", "utf-8", null);
    }
}
